<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e) {
        // Code that runs on application startup
    }
    
    void Application_End(object sender, EventArgs e) {
        //  Code that runs on application shutdown
        ScrewTurn.Wiki.StartupTools.Shutdown();
    }
	
	bool CheckWritePermissions(string dir) {
		string file = dir + "TestFile.txt";
		
		bool canWrite = true;
		
		System.IO.FileStream fs = null;
		try {
			fs = System.IO.File.Create(file);
			fs.Write(Encoding.ASCII.GetBytes("Hello"), 0, 5);
		}
		catch {
			canWrite = false;
		}
		finally {
			try {
				if(fs != null) fs.Close();
				System.IO.File.Delete(file);
			}
			catch {
				canWrite = false;
			}
		}
		
		return canWrite;
	}

	private void FailAndShutdown(string message) {
		HttpContext.Current.Response.ClearContent();
		HttpContext.Current.Response.Write(message);
		HttpContext.Current.Response.End();
		HttpRuntime.UnloadAppDomain();
	}
	
    void Application_BeginRequest(object sender, EventArgs e) {
		if(Application["StartupOK"] == null) {
			Application.Lock();
			if(Application["StartupOK"] == null) {
				// Verify write permissions in public directory, if needed
				string dir = HttpContext.Current.Request.PhysicalApplicationPath +
				System.Web.Configuration.WebConfigurationManager.AppSettings["PublicDirectory"];

				if(!CheckWritePermissions(dir)) {
					FailAndShutdown("<p style=\"color: #FF0000;\">Error: cannot write into the public directory.<br />Please check the permissions of the directory " + dir + "</p>");
					return;
				}

				// All is OK, proceed with normal startup operations
				Application["StartupOK"] = "OK";
			}

			Exception ex = ScrewTurn.Wiki.StartupTools.Startup();
			if(ex != null) {
				FailAndShutdown("<p style=\"color: #FF0000;\">Error: an exception occurred during initialization.<br /><br />" + ex.ToString().Replace("\n", "<br />") + "</p>");
				return;
			}
			
			Application.UnLock();
		}
		
        // Extract the physical page name, i.e. MainPage.ashx
        string pageName = System.IO.Path.GetFileNameWithoutExtension(HttpContext.Current.Request.PhysicalPath);
        // Exctract the extension, i.e. .ashx
        string ext = System.IO.Path.GetExtension(HttpContext.Current.Request.PhysicalPath).ToLowerInvariant();
        // Remove trailing dot, .ashx -> ashx
        if(ext.Length > 0) ext = ext.Substring(1);
        string qs = "";
        try {
            // This might throw exceptions if 3rd party modules interefer with the request pipeline
            qs = HttpContext.Current.Request.Url.Query.Replace("?", "&");
        }
        catch { }
        if(ext.Equals("ashx")) {
            // Demand the request to Default.aspx
            HttpContext.Current.RewritePath("~/Default.aspx?Page=" + pageName + qs);
        }
    }  
        
    void Application_Error(object sender, EventArgs e) {
        // Code that runs when an unhandled error occurs
        Exception ex = Server.GetLastError();
        if(ex is HttpException) {
            // Tries to redirect an inexistent .aspx page to a probably existent .ashx page
            HttpException hx = (HttpException)ex;
            if(hx.GetHttpCode() == 404) {
                string page = System.IO.Path.GetFileNameWithoutExtension(Request.PhysicalPath);
                Response.Redirect(page + ScrewTurn.Wiki.Settings.PageExtension);
                return;
            }
        }
        LogError(Server.GetLastError());
        //Response.Redirect("Error.aspx");
       // TODO: Uncomment in stable release
    }

    private void LogError(Exception ex) {
        if(ex.InnerException != null) ex = ex.InnerException;
        ScrewTurn.Wiki.Log.LogEntry(HttpContext.Current.Request.Url.ToString() + "\n" + ex.Source + " thrown " + ex.GetType().ToString() + "\n" + ex.Message + "\n" + ex.StackTrace, ScrewTurn.Wiki.EntryType.Error, "SYSTEM");
    }   

    void Session_Start(object sender, EventArgs e) {
        // Code that runs when a new session is started
        ScrewTurn.Wiki.Users.OnlineUsers++;
        ScrewTurn.Wiki.SessionFacade.Breadcrumbs = new ScrewTurn.Wiki.BreadcrumbsManager();
    }

    void Session_End(object sender, EventArgs e) {
        // Code that runs when a session ends. 
        // Note: The Session_End event is raised only when the sessionstate mode
        // is set to InProc in the Web.config file. If session mode is set to StateServer 
        // or SQLServer, the event is not raised.
        ScrewTurn.Wiki.Users.OnlineUsers--;
    }
       
</script>
